import JSZip from "jszip";
import XmlJs from "xml-js";
import { Sheet, Topic } from "./models";

/**
 *
 * @param {Topic[]} children
 */
function parseTree(children) {
  if (!children) {
    return;
  }
  return children.map((subTopic) => {
    const styles = subTopic.style?.resolve();
    return {
      id: subTopic.id,
      label: subTopic.title,
      style: styles?.style,
      labelCfg: {
        style: styles.labelStyle,
      },
      children: parseTree(subTopic?.children?.attached),
      collapsed: subTopic.branch === "folded",
    };
  });
}


function parseXmlTopic(data) {
  const attrs = data._attributes
  const topic = {
    id: attrs.id,
    structureClass: attrs['structure-class'],
    class: 'topic',
    title: data.title._text
  }
  if (attrs.branch) {
    topic.branch = attrs.branch
  }

  let children = data.children?.topics?.topic

  if (children) {
    if (!Array.isArray(children)) {
      children = [children]
    }
    topic.children = {
      attached: children.map(item => parseXmlTopic(item))
    }
  }


  return topic
}

function parseXmlData(content) {
  const data = XmlJs.xml2js(content, {
    compact: true
  })['xmap-content']
  const result = []
  const sheet = {
    class: 'sheet',
    id: data.sheet._attributes.id,
    theme: {
      id: data.sheet._attributes.theme,
    },
    rootTopic: parseXmlTopic(data.sheet.topic)
  }

  result.push(sheet)
  return result
}


/**
 *
 * @param {ArrayBuffer} buffer
 * @returns {Promise<Array<Sheet>>}
 */
async function load(buffer) {
  const zip = await JSZip.loadAsync(buffer);
  let contentFile = zip.file("content.json")

  let data
  if (contentFile) {
    const content = await contentFile.async("string");
    data = JSON.parse(content)
  } else {
    contentFile = zip.file("content.xml");
    if (!contentFile) {
      throw new Error("不支持的 XMind 版本，仅支持 >= 8.0");
    }
    const content = await contentFile.async("string")
    data = parseXmlData(content)
  }

  return data.map((item) => Sheet.load(item));
}

/**
 *
 * @param {Sheet} sheet
 */
function resolve(sheet) {
  const root = sheet.rootTopic;
  const tree = {
    id: root.id,
    label: root.title,
    children: parseTree(root?.children?.attached),
    style: {
      lineWidth: 5
    },
    labelCfg: {
      style: {
        fontWeight: 'bold'
      }
    }
  };
  return tree;
}

export default {
  load,
  resolve,
};
